const Get = require('../template')

console.log("=== Get 高级方法测试 ===")

// 测试深度获取
console.log(
  "深度获取:", (() => {
    const obj = { a: { b: { c: { d: { e: 'deep' } } } } }

    return Get.getDeep(obj, 'a.b.c.d.e', 'default', 5) === 'deep' &&
      Get.getDeep(obj, 'a.b.c.d.e', 'default', 3) === 'default' &&
      Get.getDeep(obj, 'a.b.c.d.e', 'default', 10) === 'deep'
  })()
)

// 测试条件获取
console.log(
  "条件获取:", (() => {
    const obj = { a: 1, b: 2, c: 3, d: 4 }

    return Get.getWithCondition(obj, 'a', 'default', (value, key) => value > 0) === 1 &&
      Get.getWithCondition(obj, 'b', 'default', (value, key) => value > 5) === 'default' &&
      Get.getWithCondition(obj, 'c', 'default', (value, key) => key === 'c') === 3
  })()
)

// 测试类型检查获取
console.log(
  "类型检查获取:", (() => {
    const obj = { a: 1, b: 'test', c: true, d: null }

    return Get.getWithType(obj, 'a', 'default', 'number') === 1 &&
      Get.getWithType(obj, 'b', 'default', 'string') === 'test' &&
      Get.getWithType(obj, 'c', 'default', 'boolean') === true &&
      Get.getWithType(obj, 'a', 'default', 'string') === 'default' &&
      Get.getWithType(obj, 'b', 'default', 'number') === 'default'
  })()
)

// 测试转换获取
console.log(
  "转换获取:", (() => {
    const obj = { a: 1, b: 'test', c: '42' }

    return Get.getWithTransform(obj, 'a', 'default', value => value * 2) === 2 &&
      Get.getWithTransform(obj, 'b', 'default', value => value.toUpperCase()) === 'TEST' &&
      Get.getWithTransform(obj, 'c', 'default', value => parseInt(value)) === 42 &&
      Get.getWithTransform(obj, 'd', 'default', value => value) === 'default'
  })()
)

// 测试验证获取
console.log(
  "验证获取:", (() => {
    const obj = { name: 'John', age: 30, email: 'john@example.com' }
    const schema = {
      name: { type: 'string', required: true },
      age: { type: 'number', min: 0, max: 150 },
      email: { type: 'string', pattern: /@/ }
    }

    try {
      return Get.getWithValidation(obj, 'name', 'default', schema) === 'John' &&
        Get.getWithValidation(obj, 'age', 'default', schema) === 30 &&
        Get.getWithValidation(obj, 'email', 'default', schema) === 'john@example.com' &&
        Get.getWithValidation(obj, 'nonexistent', 'default', schema) === 'default'
    } catch (error) {
      return false
    }
  })()
)

// 测试多路径获取
console.log(
  "多路径获取:", (() => {
    const obj = { a: { b: 1 }, c: { d: 2 }, e: { f: 3 } }
    const paths = ['a.b', 'c.d', 'e.f', 'nonexistent']

    const results = Get.getMultiple(obj, paths, 'default')

    return Array.isArray(results) &&
      results.length === 4 &&
      results[0] === 1 &&
      results[1] === 2 &&
      results[2] === 3 &&
      results[3] === 'default'
  })()
)

// 测试异步获取
console.log(
  "异步获取:", (() => {
    const obj = { a: 1, b: 'test' }

    return Get.getAsync(obj, 'a', 'default', async (value, key) => {
      await new Promise(resolve => setTimeout(resolve, 1))
      return value * 2
    }).then(result => {
      return result === 2
    }).catch(() => false)
  })()
)

// 测试并发获取
console.log(
  "并发获取:", (() => {
    const obj = { a: 1, b: 2, c: 3, d: 4, e: 5 }
    const paths = ['a', 'b', 'c', 'd', 'e']

    return Get.getConcurrent(obj, paths, 'default', async (value, key) => {
      await new Promise(resolve => setTimeout(resolve, 1))
      return value * 2
    }, 3).then(results => {
      return Array.isArray(results) &&
        results.length === 5 &&
        results[0] === 2 &&
        results[1] === 4 &&
        results[2] === 6 &&
        results[3] === 8 &&
        results[4] === 10
    }).catch(() => false)
  })()
)

// 测试统计获取
console.log(
  "统计获取:", (() => {
    const obj = { a: { b: { c: 1 } }, d: { e: 2 } }
    const result = Get.getWithStats(obj, 'a.b.c', 'default')

    return typeof result === 'object' &&
      typeof result.data === 'number' &&
      result.data === 1 &&
      typeof result.stats === 'object' &&
      result.stats.depth > 0 &&
      result.stats.pathLength > 0
  })()
)

// 测试复杂嵌套结构获取
console.log(
  "复杂嵌套结构获取:", (() => {
    const obj = {
      user: {
        profile: {
          personal: {
            name: 'John',
            age: 30,
            address: {
              city: 'New York',
              country: 'USA',
              coordinates: {
                lat: 40.7128,
                lng: -74.0060
              }
            }
          },
          preferences: {
            theme: 'dark',
            language: 'en',
            notifications: {
              email: true,
              push: false,
              sms: true
            }
          }
        },
        posts: [
          { title: 'Post 1', likes: 10, comments: [{ text: 'Great!' }] },
          { title: 'Post 2', likes: 20, comments: [{ text: 'Awesome!' }] }
        ]
      },
      meta: { total: 2, page: 1 }
    }

    return Get.get(obj, 'user.profile.personal.name') === 'John' &&
      Get.get(obj, 'user.profile.personal.age') === 30 &&
      Get.get(obj, 'user.profile.personal.address.city') === 'New York' &&
      Get.get(obj, 'user.profile.personal.address.country') === 'USA' &&
      Get.get(obj, 'user.profile.personal.address.coordinates.lat') === 40.7128 &&
      Get.get(obj, 'user.profile.personal.address.coordinates.lng') === -74.0060 &&
      Get.get(obj, 'user.profile.preferences.theme') === 'dark' &&
      Get.get(obj, 'user.profile.preferences.language') === 'en' &&
      Get.get(obj, 'user.profile.preferences.notifications.email') === true &&
      Get.get(obj, 'user.profile.preferences.notifications.push') === false &&
      Get.get(obj, 'user.profile.preferences.notifications.sms') === true &&
      Get.get(obj, 'user.posts.0.title') === 'Post 1' &&
      Get.get(obj, 'user.posts.0.likes') === 10 &&
      Get.get(obj, 'user.posts.0.comments.0.text') === 'Great!' &&
      Get.get(obj, 'user.posts.1.title') === 'Post 2' &&
      Get.get(obj, 'user.posts.1.likes') === 20 &&
      Get.get(obj, 'user.posts.1.comments.0.text') === 'Awesome!' &&
      Get.get(obj, 'meta.total') === 2 &&
      Get.get(obj, 'meta.page') === 1
  })()
)

// 测试数组路径获取
console.log(
  "数组路径获取:", (() => {
    const obj = { data: { items: [1, 2, 3] } }
    const path = ['data', 'items', '0']

    return Get.get(obj, path) === 1 &&
      Get.get(obj, ['data', 'items', '1']) === 2 &&
      Get.get(obj, ['data', 'items', '2']) === 3 &&
      Get.get(obj, ['data', 'items', '3']) === undefined
  })()
)

// 测试边界情况获取
console.log(
  "边界情况获取:", (() => {
    const obj = { a: 1 }

    return Get.get(obj, '') === undefined &&
      Get.get(obj, ' ') === undefined &&
      Get.get(obj, 'a ') === undefined &&
      Get.get(obj, ' a') === undefined &&
      Get.get(obj, 'a.b.c.d.e.f.g.h') === undefined
  })()
)

// 测试特殊字符路径获取
console.log(
  "特殊字符路径获取:", (() => {
    const obj = { 'key-with-dash': 'value1', 'key.with.dot': 'value2', 'key with space': 'value3' }

    return Get.get(obj, 'key-with-dash') === 'value1' &&
      Get.get(obj, 'key.with.dot') === 'value2' &&
      Get.get(obj, 'key with space') === 'value3'
  })()
)

// 测试数字键路径获取
console.log(
  "数字键路径获取:", (() => {
    const obj = { 0: 'zero', 1: 'one', 2: 'two' }

    return Get.get(obj, '0') === 'zero' &&
      Get.get(obj, '1') === 'one' &&
      Get.get(obj, '2') === 'two' &&
      Get.get(obj, '3') === undefined
  })()
)

// 测试布尔值键路径获取
console.log(
  "布尔值键路径获取:", (() => {
    const obj = { true: 'yes', false: 'no' }

    return Get.get(obj, 'true') === 'yes' &&
      Get.get(obj, 'false') === 'no'
  })()
)

// 测试空字符串键路径获取
console.log(
  "空字符串键路径获取:", (() => {
    const obj = { '': 'empty key' }

    return Get.get(obj, '') === 'empty key'
  })()
)

// 测试原型链属性获取
console.log(
  "原型链属性获取:", (() => {
    function TestClass() {
      this.instanceProp = 'instance'
    }
    TestClass.prototype.prototypeProp = 'prototype'

    const instance = new TestClass()

    return Get.get(instance, 'instanceProp') === 'instance' &&
      Get.get(instance, 'prototypeProp') === 'prototype' &&
      Get.get(instance, 'nonexistentProp') === undefined
  })()
)

// 测试Symbol键路径获取
console.log(
  "Symbol键路径获取:", (() => {
    const sym = Symbol('test')
    const obj = { [sym]: 'symbol value' }

    return Get.get(obj, sym) === 'symbol value'
  })()
)

// 测试复杂数组结构获取
console.log(
  "复杂数组结构获取:", (() => {
    const obj = {
      matrix: [
        [1, 2, 3],
        [4, 5, 6],
        [7, 8, 9]
      ]
    }

    return Get.get(obj, 'matrix.0.0') === 1 &&
      Get.get(obj, 'matrix.0.1') === 2 &&
      Get.get(obj, 'matrix.0.2') === 3 &&
      Get.get(obj, 'matrix.1.0') === 4 &&
      Get.get(obj, 'matrix.1.1') === 5 &&
      Get.get(obj, 'matrix.1.2') === 6 &&
      Get.get(obj, 'matrix.2.0') === 7 &&
      Get.get(obj, 'matrix.2.1') === 8 &&
      Get.get(obj, 'matrix.2.2') === 9
  })()
)

console.log("=== Get 高级方法测试完成 ===")
